﻿using AutoMapper;
using QYmall.Core.Common.Emum;
using QYmall.Core.Common.Extensions;
using QYmall.Core.Common.Helper;
using QYmall.Core.DBFactory.Database;
using QYmall.Core.IServices;
using QYmall.Core.Model.Models;
using QYmall.Core.Model.ViewModels;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace QYmall.Core.Services
{
    /// <summary>
    /// 商户提现申请接口实现
    /// </summary>
    public class MerchantCashService : BaseService, IMerchantCashService
    {
        private readonly IUserService _userService;
        private readonly IMapper _mapper;

        public MerchantCashService(IDbContextFactory contentFactory,
            IUserService userService, IMapper mapper) : base(contentFactory)
        {
            _userService = userService;
            _mapper = mapper;
        }

        /// <summary>
        /// 查询一条记录
        /// </summary>
        public async Task<MerchantCash?> QueryAsync(Expression<Func<MerchantCash, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = await _context.Set<MerchantCash>()
                .Include(x => x.Merchant)
                .FirstOrDefaultAsync(funcWhere);
            return result;
        }

        /// <summary>
        /// 查询指定数量列表
        /// </summary>
        public async Task<IEnumerable<MerchantCash>> QueryListAsync(int top, Expression<Func<MerchantCash, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = _context.Set<MerchantCash>()
                .Include(x => x.Merchant)
                .Where(funcWhere).OrderByBatch(orderBy);//调用Linq扩展类进行排序
            if (top > 0) result = result.Take(top);//等于0显示所有数据
            return await result.ToListAsync();
        }

        /// <summary>
        /// 查询分页列表
        /// </summary>
        public async Task<PaginationList<MerchantCash>> QueryPageAsync(int pageSize, int pageIndex, Expression<Func<MerchantCash, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = _context.Set<MerchantCash>()
                .Include(x => x.Merchant)
                .Where(funcWhere).OrderByBatch(orderBy);//调用Linq扩展类排序
            return await PaginationList<MerchantCash>.CreateAsync(pageIndex, pageSize, result);
        }

        /// <summary>
        /// 申请提现
        /// </summary>
        public async Task<MerchantCash> AddAsync(MerchantCashEditDto modelDto, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //检查提现金额是否正确
            if (modelDto.TransferAmount <= 0)
            {
                throw new ResponseException("提现金额必须大于零");
            }
            //检查是否重复提交申请
            if (await _context.Set<MerchantCash>().FirstOrDefaultAsync(x => x.MerchantId == modelDto.MerchantId && x.HandleStatus < 3) != null)
            {
                throw new ResponseException("已有申请尚未处理，请勿重复提交");
            }
            //检查收款方式是否存在
            var payinfoModel = await _context.Set<MerchantPayinfo>().FirstOrDefaultAsync(x => x.Id == modelDto.PayinfoId);
            if (payinfoModel == null)
            {
                throw new ResponseException("收款方式不存在，请检查再提交");
            }
            //检查是否有足够的可用余额=余额-不可用余额
            var merchantModel = await _context.Set<Merchants>().FirstOrDefaultAsync(x => x.Id == modelDto.MerchantId && x.IsLock == 0);
            if (merchantModel == null)
            {
                throw new ResponseException("商户不存在或被禁用");
            }
            var balanceAmount = merchantModel.Amount - merchantModel.FrozenAmount;
            if (balanceAmount <= 0 || balanceAmount < modelDto.TransferAmount)
            {
                throw new ResponseException("商户余额不足，无法申请提现");
            }
            //映射成实体
            var model = _mapper.Map<MerchantCash>(modelDto);
            model.PayType = payinfoModel.PayType;
            model.FullName = payinfoModel.FullName;
            model.BankName = payinfoModel.BankName;
            model.AccountNo = payinfoModel.AccountNo;
            model.QRCode = payinfoModel.QRCode;
            model.BalanceAmount = balanceAmount;
            model.AddTime = DateTime.Now;
            model.HandleStatus = 1;
            //保存数据
            await _context.Set<MerchantCash>().AddAsync(model);
            var result = await this.SaveAsync();
            if (!result)
            {
                throw new ResponseException("数据保存时发生意外错误");
            }
            return model;
        }

        /// <summary>
        /// 修改记录
        /// </summary>
        public async Task<bool> UpdateAsync(long id, MerchantCashEditDto modelDto, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //检查提现金额是否正确
            if (modelDto.TransferAmount <= 0)
            {
                throw new ResponseException("提现金额必须大于零");
            }
            //检查记录是否存在
            var model = await _context.Set<MerchantCash>().FirstOrDefaultAsync(x => x.Id == id);
            if (model == null)
            {
                throw new ResponseException($"数据不存在或已删除");
            }
            //检查是否可以修改
            if (model.HandleStatus == 2 || model.HandleStatus == 3)
            {
                throw new ResponseException("申请已处于审核状态，不可修改");
            }
            //检查收款方式是否存在
            var payinfoModel = await _context.Set<MerchantPayinfo>().FirstOrDefaultAsync(x => x.Id == modelDto.PayinfoId);
            if (payinfoModel == null)
            {
                throw new ResponseException("收款方式不存在，请检查再提交");
            }
            //检查是否有足够的可用余额=余额-不可用余额
            var merchantModel = await _context.Set<Merchants>().FirstOrDefaultAsync(x => x.Id == modelDto.MerchantId && x.IsLock == 0);
            if (merchantModel == null)
            {
                throw new ResponseException("商户不存在或被禁用");
            }
            var balanceAmount = merchantModel.Amount - merchantModel.FrozenAmount;
            if (balanceAmount <= 0 || balanceAmount < modelDto.TransferAmount)
            {
                throw new ResponseException("商户余额不足，无法申请提现");
            }
            //映射实体
            _mapper.Map(modelDto, model);
            model.PayType = payinfoModel.PayType;
            model.FullName = payinfoModel.FullName;
            model.BankName = payinfoModel.BankName;
            model.AccountNo = payinfoModel.AccountNo;
            model.QRCode = payinfoModel.QRCode;
            model.BalanceAmount = balanceAmount;
            model.HandleStatus = 1;
            //保存数据
            _context.Set<MerchantCash>().Update(model);
            return await this.SaveAsync();
        }

        /// <summary>
        /// 管理员:同意,拒绝,转账
        /// </summary>
        public async Task<bool> HandleAsync(long id, MerchantCashHandleDto modelDto, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //检查记录是否存在
            var model = await _context.Set<MerchantCash>().FirstOrDefaultAsync(x => x.Id == id);
            if (model == null)
            {
                throw new ResponseException($"数据不存在或已删除");
            }
            if (model.HandleStatus > 2)
            {
                throw new ResponseException($"该申请已经完结，请确认后操作");
            }
            //检查是否有足够的可用余额=余额-不可用余额
            var merchantModel = await _context.Set<Merchants>().FirstOrDefaultAsync(x => x.Id == model.MerchantId && x.IsLock == 0);
            if (merchantModel == null)
            {
                throw new ResponseException("商户不存在或被禁用");
            }
            //通过审核
            if (modelDto.HandleStatus == 2)
            {
                var balanceAmount = merchantModel.Amount - merchantModel.FrozenAmount;
                if (balanceAmount <= 0 || balanceAmount < model.TransferAmount)
                {
                    throw new ResponseException("商户余额不足，无法申请提现");
                }
                //增加不可用余额
                merchantModel.FrozenAmount += model.TransferAmount;
                _context.Set<Merchants>().Update(merchantModel);
            }
            //完成提现
            if (modelDto.HandleStatus == 3)
            {
                if (merchantModel.Amount < model.TransferAmount)
                {
                    throw new ResponseException("商户余额不足，无法完成提现");
                }
                //增加资金日志
                await _context.Set<MerchantAmountLog>().AddAsync(new MerchantAmountLog
                {
                    MerchantId = model.MerchantId,
                    Amount = model.TransferAmount * -1,
                    AddTime = DateTime.Now,
                    Remark = $"申请提现金额:{model.TransferAmount}元"
                });
                merchantModel.FrozenAmount -= model.TransferAmount;
                merchantModel.Amount -= model.TransferAmount;
                _context.Set<Merchants>().Update(merchantModel);
            }
            //如果已经同意，完成时又驳回，则需要解冻不可用余额
            if (modelDto.HandleStatus == 4 && model.HandleStatus == 2)
            {
                merchantModel.FrozenAmount -= model.TransferAmount;
                _context.Set<Merchants>().Update(merchantModel);
            }
            //映射实体
            _mapper.Map(modelDto, model);
            model.HandleBy = await _userService.GetUserNameAsync();
            model.HandleTime = DateTime.Now;
            _context.Set<MerchantCash>().Update(model);

            return await this.SaveAsync();
        }
    }
}
